﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Apq.IO
{
	/// <summary>
	/// 文件分块信息(单块)
	/// </summary>
	public class FileSection
	{
		/// <summary>
		/// 完整文件名
		/// </summary>
		[DefaultValue("")]
		public string FullFileName { get; set; }
		/// <summary>
		/// 分块编号
		/// </summary>
		[DefaultValue(0)]
		public int SubNo { get; set; }
		/// <summary>
		/// 文件大小(B)
		/// </summary>
		[DefaultValue(100)]
		public long TotalSize { get; set; }
		/// <summary>
		/// 起点
		/// </summary>
		[DefaultValue(0)]
		public long PosBegin { get; set; }
		/// <summary>
		/// 终点(%lt;=0表示直到文件结尾)
		/// </summary>
		[DefaultValue(0)]
		public long PosEnd { get; set; }
		/// <summary>
		/// 分块大小(B)
		/// </summary>
		[DefaultValue(1)]
		public long SecSize { get; set; }

		/// <summary>
		/// 默认构造函数,为成员赋予默认值
		/// </summary>
		public FileSection()
		{
			FullFileName = string.Empty;
			SubNo = 0;
			TotalSize = 100;
			PosBegin = 0;
			PosEnd = 0;
			SecSize = 1;
		}

		/// <summary>
		/// 文件分块信息(单块)
		/// </summary>
		public FileSection(long SecSize, string FullFileName = "", int SubNo = 0, long TotalSize = 100, long PosBegin = 0, long PosEnd = 0)
			: this()
		{
			this.SecSize = SecSize;

			this.FullFileName = FullFileName;
			this.SubNo = SubNo;
			this.TotalSize = TotalSize;
			this.PosBegin = PosBegin;
			this.PosEnd = PosEnd;
		}

		/// <summary>
		/// 根据分块总数重新计算本块起点
		/// </summary>
		public long ReCalcPos()
		{
			return PosBegin = SecSize * SubNo;
		}

		/// <summary>
		/// 文件分块,单块最小为8KB,最大不超过总大小(Total)
		/// </summary>
		/// <param name="Total">总大小(B)</param>
		/// <param name="Secs">预设分块数,最终分块数不会超过该值</param>
		/// <param name="FullFileName">文件全名</param>
		/// <returns></returns>
		public static List<FileSection> CalcSection(long Total, int Secs = 5, string FullFileName = "")
		{
			List<FileSection> lst = new List<FileSection>(Secs);

			double dTotal = Apq.Convert.ChangeType<double>(Total);
			// 单块大小
			long secSize = Apq.Convert.ChangeType<long>(Math.Ceiling(dTotal / Secs));
			if (secSize < 8192)
			{
				secSize = 8192;
			}
			if (secSize > Total)
			{
				secSize = Total;
			}

			// 已分配的大小
			long secd = 0;

			for (int i = 0; i < Secs; i++)
			{
				long posBegin = secd;
				long posEnd = secd + secSize;
				if (posEnd > Total)
				{
					posEnd = Total;
				}
				FileSection fs = new FileSection(posEnd - posBegin, FullFileName, i, Total, posBegin, posEnd);
				lst.Add(fs);

				secd += secSize;
				if (secd >= Total)
				{
					break;
				}
			}

			return lst;
		}

		/// <summary>
		/// 文件分块(每块结束点均为结尾)
		/// </summary>
		/// <param name="Total">总大小(B)</param>
		/// <param name="Secs">分块数</param>
		/// <param name="FullFileName">文件全名</param>
		/// <returns></returns>
		public static List<FileSection> CalcSectionEnd(long Total, int Secs = 5, string FullFileName = "")
		{
			List<FileSection> lst = CalcSection(Total, Secs, FullFileName);
			foreach (FileSection sec in lst)
			{
				sec.PosEnd = sec.TotalSize;
			}

			return lst;
		}

		#region 扩展属性,方便多线程等
		/// <summary>
		/// 线程等待对象,仅提供存储功能
		/// </summary>
		public System.Threading.ManualResetEvent ManualResetEvent { get; set; }
		#endregion
	}
}
